/*
 * @Description: 测试数组、ArrayList、LinkedList、Vector的插入、获取性能对比
 * @Version: 
 * @Author: Weixin Zhu
 * @Date: 2020-11-24 15:57:05
 * @LastEditors: Weixin Zhu
 * @LastEditTime: 2020-12-09 15:27:23
 */
package com.zwx.algorithms.basic;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

import cn.hutool.core.util.RandomUtil;


public class PerfprmanceTester {
	private static final int TIMES = 100000;
	private static final ThreadLocalRandom random = RandomUtil.getRandom();

	/**
	 * Array Tester
	 */
	public static abstract class ArrayTester {
		private String operation;

		public ArrayTester(String operation) {
			this.operation = operation;
		}

		public abstract void test(String[] array);

		public String getOperation() {
			return operation;
		}
	}

	/**
	 * List Test
	 */
	public static abstract class Tester {
		private String operation;

		public Tester(String operation) {
			this.operation = operation;
		}

		public abstract void test(List<String> list);

		public String getOperation() {
			return operation;
		}
	}

	static ArrayTester arrayindexTester = new ArrayTester("arrayindex") {
		public void test(String[] array) {
			@SuppressWarnings("unused")
			String temp;
			for (int j = 0; j < 10; j++) {
				for (int i = 0; i < array.length; i++) {
					temp = array[i];
				}
			}
		}
	};
	static ArrayTester arrayRandomindexTester = new ArrayTester("arrayrandomindex") {
		public void test(String[] array) {
			@SuppressWarnings("unused")
			String temp;
			int len = array.length;
			for (int j = 0; j < 10; j++) {
				for (int i = 0; i < array.length; i++) {
					temp = array[random.nextInt(len)];
				}
			}
		}
	};

	/**
	 * Iterator Test 循环遍历整个集合10次
	 */
	static Tester iterateTester = new Tester("iterate") {
		public void test(List<String> list) {
			for (int i = 0; i < 10; i++) {
				Iterator<String> it = list.iterator();
				while (it.hasNext()) {
					it.next();
				}
			}
		}
	};
	/**
	 * For loop Test 循环get整个集合10次
	 */
	static Tester getTester = new Tester("get") {
		public void test(List<String> list) {
			for (int j = 0; j < 10; j++) {
				for (int i = 0; i < list.size(); i++) {
					list.get(i);
				}
			}
		}
	};
	/**
	 * Random get Test 随机get整个集合10次
	 */
	static Tester randomGetTester = new Tester("randomget") {
		public void test(List<String> list) {
			int len = list.size();
			for (int j = 0; j < 10; j++) {
				for (int i = 0; i < list.size(); i++) {
					list.get(random.nextInt(len));
				}
			}
		}
	};
	/**
	 * listIterator add Test
	 */
	static Tester insertTester = new Tester("insert") {
		public void test(List<String> list) {
			ListIterator<String> it = list.listIterator(list.size() / 2);
			for (int i = 0; i < TIMES / 2; i++) {
				it.add("hello2");
			}
		}
	};
	/**
	 * listIterator remove Test
	 */
	static Tester removeTester = new Tester("remove") {
		public void test(List<String> list) {
			ListIterator<String> it = list.listIterator();
			while (it.hasNext()) {
				it.next();
				it.remove();
			}
		}
	};

	static public void testJavaArray(String[] array) {
		ArrayTester[] testers = { arrayindexTester };
		test(testers, array);
	}

	static public void testJavaArrayASList(List<String> list) {
		Tester[] testers = { iterateTester, getTester };
		test(testers, list);
	}

	static public void testList(List<String> list) {
		//Tester[] testers = { insertTester, iterateTester, getTester, removeTester };
		Tester[] testers = {  iterateTester, getTester };
		test(testers, list);
	}

	static public void test(Tester[] testers, List<String> list) {
		for (int i = 0; i < testers.length; i++) {
			System.out.print(testers[i].getOperation() + "操作:  ");
			long t1 = System.currentTimeMillis();
			testers[i].test(list);
			long t2 = System.currentTimeMillis();
			System.out.print(t2 - t1 + "ms");
			System.out.println();
		}
	}

	static public void test(ArrayTester[] testers, String[] array) {
		for (int i = 0; i < testers.length; i++) {
			System.out.print(testers[i].getOperation() + "操作:  ");
			long t1 = System.currentTimeMillis();
			testers[i].test(array);
			long t2 = System.currentTimeMillis();
			System.out.print(t2 - t1 + "ms");
			System.out.println();
		}
	}

	public static void main(String[] args) {
		List<String> list = null;
		System.out.println("---测试JAVA数组---");
		String[] ss = new String[TIMES];
		// 用“hello”填充数组
		Arrays.fill(ss, "hello");
		testJavaArray(ss);
		// 用Arrays.asList转成集合，比较特殊，返回的是：java.util.Arrays.ArrayList，
		// java.util.Arrays.ArrayList，是工具类 Arrays 的一个内部静态类，它没有完全实现List的方法，而
		// ArrayList直接实现了List 接口，实现了List所有方法。
		System.out.println("---java.util.Arrays.ArrayList---");
		list = Arrays.asList(ss);
		testJavaArrayASList(list);

		//ss = new String[TIMES / 2];
		ss = new String[TIMES];
		Arrays.fill(ss, "hello");
		Collection<String> col = Arrays.asList(ss);

		System.out.println("---测试ArrayList---");
		list = new ArrayList<String>();
		list.addAll(col);
		testList(list);

		System.out.println("---测试Vector---");
		list = new Vector<String>();
		list.addAll(col);
		testList(list);

		System.out.println("---测试LinkedList---");
		list = new LinkedList<String>();
		list.addAll(col);
		testList(list);
	}
}